﻿#region Using directives

using Microsoft.VisualStudio.TestTools.UnitTesting;


using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Gezel.Parser;
using Weazel.Gezel.Model;
using Weazel.Gezel.Model.Errors;
using Weazel.Math;

#endregion

namespace Weazel.Gezel.Parser.Test
{
  [TestClass]
  public class TestParsePortList
  {
    [TestMethod]
    public void TestSinglePortList()
    {
      Tokenizer t = new Tokenizer("in a : ns(10)");

      List<ParseError> errors = new List<ParseError>();

      int portPos = 0;

      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);
      // ParsePorts.parsePortElement(ref errors, new Set<Token>(Token.Eof), t);

      Assert.AreEqual(0, t.Errors.Count);

      Assert.AreEqual(1, result.Count);

      Assert.AreEqual("a", result[0].Name);
      Assert.AreEqual(10, result[0].Type.Width);
      Assert.IsFalse(result[0].Type.Signed);
      Assert.IsTrue(result[0].InPort);
    }

    [TestMethod]
    public void TestMultiplePortList()
    {
      Tokenizer t = new Tokenizer("in a, b, c : ns(10)");

      List<ParseError> errors = new List<ParseError>();

      int portPos = 0;

      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);

      Assert.AreEqual(0, t.Errors.Count);

      Assert.AreEqual(3, result.Count);

      Assert.AreEqual("a", result[0].Name);
      Assert.AreEqual(10, result[0].Type.Width);
      Assert.IsFalse(result[0].Type.Signed);
      Assert.IsTrue(result[0].InPort);

      Assert.AreEqual("b", result[1].Name);
      Assert.AreEqual(10, result[1].Type.Width);
      Assert.IsFalse(result[1].Type.Signed);
      Assert.IsTrue(result[1].InPort);

      Assert.AreEqual("c", result[2].Name);
      Assert.AreEqual(10, result[2].Type.Width);
      Assert.IsFalse(result[2].Type.Signed);
      Assert.IsTrue(result[2].InPort);
    }

    [TestMethod]
    public void TestSinglePortListWithError1()
    {
      Tokenizer t = new Tokenizer("in a ns(10)"); // missing colon

      List<ParseError> errors = new List<ParseError>();

      int portPos = 0;

      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);

      Assert.AreEqual(1, t.Errors.Count);

      /*
      foreach (ParseError error in t.Errors)
        System.Windows.Forms.MessageBox.Show(error.ToString());
      */

//      Assert.AreEqual("a", result[0].Name);
//      Assert.AreEqual(10, result[0].Type.Width);
//      Assert.IsFalse(result[0].Type.Signed);
//      Assert.IsTrue(result[0].InPort);
    }

    [TestMethod]
    public void TestSinglePortListWithError2()
    {
      Tokenizer t = new Tokenizer("in a : ks(10)"); // wrong signal type

      List<ParseError> errors = new List<ParseError>();

      int portPos = 0;
      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);

      Assert.AreEqual(1, t.Errors.Count);

      /*
      foreach (ParseError error in t.Errors)
        System.Windows.Forms.MessageBox.Show(error.ToString());
      */
    }

    [TestMethod]
    public void TestSinglePortListWithError3()
    {
      Tokenizer t = new Tokenizer("in in : tc(10)"); // error in identifier

      List<ParseError> errors = new List<ParseError>();


      int portPos = 0;
      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);

      Assert.AreEqual(1, t.Errors.Count);

      /*
      foreach (ParseError error in t.Errors)
        System.Windows.Forms.MessageBox.Show(error.ToString());
      */
    }

    [TestMethod]
    public void TestPortListWithMultiplyDefinedSymbol()
    {
      // strictly speaking this is an error but it isnt caught here ..
      Tokenizer t = new Tokenizer("in a, a : tc(10)"); // error in identifier      
      List<ParseError> errors = new List<ParseError>();
      int portPos = 0;
      List<PortInfo> result = ParsePortIoElement.Parse(new Set<Token>(Token.Eof), t, ref portPos);

      Assert.AreEqual(0, t.Errors.Count);

      // here the error should be caught ..
      t = new Tokenizer("dp mydp (in a, a : ns(5)) {}");
      Model.Model model = new Model.Model("mymodel");
      ParseDatapath.Parse(new Set<Token>(Token.Eof), t, model);

      Assert.AreEqual(1, t.Errors.Count);
      Assert.AreEqual(ParseErrorType.DuplicateSymbolDefintion, t.Errors[0].ErrorType);
    }
  }
}
